using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using Liberty.Domain.CaseManagement;
using Liberty.Domain.Kernel;
using Liberty.Domain.ServiceMemberManagement;
using Liberty.Persistence.CaseManagement;
using Liberty.Persistence;
using Peradigm.Framework.Domain.Collections;
using Peradigm.Framework.Domain.Collections.Generic;
using Peradigm.Framework.Domain.Security;
using Peradigm.Framework.Domain.Parties;
using Peradigm.Framework.OrganizationalHierarchyService;
using Peradigm.Framework.Domain.Security;
using Liberty.Domain.NoteManagement;

using Peradigm.Framework.Persistence;
using Liberty.Persistence.NoteManagement;


namespace Liberty.Application.CaseManagement
{
    [Serializable]
    public class CaseController : AbstractController
    {
        #region Constants
        private const string DEFAULT_NOTES_SORT = "DateCreated";
        #endregion

        #region Event Handlers
        #endregion

        #region Methods
        public Case CaseWith( long oid )
        {
            return this.CaseBroker.CaseWith( oid );
        }

        public List<Case> CasesFor( ServiceMember serviceMember )
        {
            return this.CaseBroker.CasesFor( serviceMember );
        }

        public List<Task> TasksFor( User aUser )
        {
#warning not complete
            List<Task> aTaskList = new List<Task>();
            return aTaskList;
        }

        public Case SaveCase( Case aCase )
        {
           return  this.CaseBroker.Save( aCase );
        }

        public List<Facility> AllFacilities()
        {
            List<Facility> facilities = new List<Facility>();
            OrganizationalUnit hierarchy = OrganizationalService.Service.GetOrganizationalHierarchy();

            foreach( Facility facility in hierarchy.AllFacilities() )
            {
                //MK- facility xml doesn't contain Oid and we need Facility.Oid to persist visit
                //remove next line when fixed.
                facility.Oid = Convert.ToInt32(facility.HspCode);
                facilities.Add( facility );
            }
            return facilities;
        }

        public List<TypeOfInjury> InjuryTypes()
        {
            CaseBroker cb = new CaseBroker( base.ConnectionString );
            return cb.InjuryTypes();
        }

        public TypeOfInjury InjuryWith( long oid )
        {
            List<TypeOfInjury> injuries = this.InjuryTypes();
            return injuries.Find( element => element.Oid == oid );
        }

        public Case NewCaseFor( User volunteer )
        {
            CaseVolunteer caseVolunteer = new CaseVolunteer( volunteer.Oid, volunteer.FirstName, volunteer.LastName );
            return new Case( caseVolunteer );
        }

        public List<Note> NotesFrom(Case aCase)
        {
            List<Note> notes = new List<Note>(aCase.Notes);
            if (notes.Count == 0)
            {
                notes = this.NotesFor(aCase);
            }
            notes.Sort(new Sorter<Note>(SortOrder.Descending, DEFAULT_NOTES_SORT));
            return notes;
        }

        public Note SaveNote( Case aCase, Note note )
        {
            NoteBroker noteBroker = new NoteBroker( this.ConnectionString );
            Note newNote = noteBroker.SaveNote( aCase, note );
            aCase.AddNote( newNote );
            return newNote;
        }

        #endregion

        #region Properties
        public CaseBroker CaseBroker
        {
            get
            {
                return this.i_CaseBroker;
            }
            set
            {
                this.i_CaseBroker = value;
            }
        }
        #endregion

        #region Private Methods

        internal List<Note> NotesFor(Case aCase)
        {
            aCase.RemoveNotes();
            NoteBroker noteBroker = new NoteBroker(this.ConnectionString);
            List<Note> notes = noteBroker.NotesFor(aCase);   

            return notes;
        }
        #endregion

        #region Private Properties
        #endregion

        #region Construction and Finalization
        public CaseController()
            : base()
        {
            string cxnString = base.ConnectionString;
            this.i_CaseBroker = new CaseBroker( cxnString );
        
        }
        #endregion

        #region Data Elements
        private CaseBroker i_CaseBroker = null;
        #endregion

    }
}
